package top.tenebrous.yzl.im.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;
import top.tenebrous.yzl.im.contants.CommonConstants;
import top.tenebrous.yzl.im.context.ImContext;
import top.tenebrous.yzl.im.enums.ChannelType;
import top.tenebrous.yzl.im.factory.channel.ChannelFactory;
import top.tenebrous.yzl.im.interceptor.ImWebsocketInterceptor;
import top.tenebrous.yzl.im.message.MessageBody;
import top.tenebrous.yzl.im.utils.WebSocketUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author yazhang6
 */
@Slf4j
@Component
public class ReceiverMessageHandler {

    @Autowired
    private ChannelFactory<MessageBody> channelFactory;

    @Autowired
    private ImContext imContext;

    public void handlerMessage(String msg, String channel) {
        // 获取接受消息的人
        Pair<String, MessageBody> messageBodyPair = parseMessage(msg);
        if (Objects.isNull(messageBodyPair) || Objects.isNull(messageBodyPair.getRight())) {
            return;
        }
        MessageBody messageBody = messageBodyPair.getRight();
        // 获取发送者session 集群模式下，发送者和接收者的session可能在不同机器，此session可能为null
        WebSocketSession fromSession = WebSocketUtils.getSession(messageBody.getFrom());

        // 执行具体方法
        channelFactory.getChannel(ChannelType.getMessageType(channel)).doHandler(fromSession, messageBodyPair.getLeft(),messageBody);
    }

    private Pair<String, MessageBody> parseMessage(String msg) {
        log.info("{} 解析消息开始: {}", CommonConstants.LOG_PREFIX, msg);
        JSONObject jsonMessage = JSON.parseObject(msg);
        Integer code = jsonMessage.getInteger("code");
        String data = jsonMessage.getString("data");
        log.info("{} 解析消息data: {}", CommonConstants.LOG_PREFIX, data);
        List<Map.Entry<ImWebsocketInterceptor, Integer>> sortList = imContext.handlerInterceptorSorted();
        // 执行扩展拦截
        for (Map.Entry<ImWebsocketInterceptor, Integer> entry : sortList) {
            data = entry.getKey().beforeImWebSocketOnParseMessageProcessor(data);
        }
        JSONObject dataJson = JSON.parseObject(data);
        MessageBody messageBody = dataJson.getObject("body", MessageBody.class);
        log.info("{} 解析消息body: {}", CommonConstants.LOG_PREFIX, JSON.toJSONString(messageBody));
        if (0 != code) {
            WebSocketSession session = WebSocketUtils.getSession(messageBody.getFrom());
            WebSocketUtils.sendError(session, null, jsonMessage.getString("消息发送失败！"), messageBody.getFrom());
            log.error("消息发送失败");
            log.error("{} 解析消息异常，发送异常消息", CommonConstants.LOG_PREFIX);
            return null;
        }
        return new MutablePair<>(dataJson.getString("type"), messageBody);
    }
}
